package flare.query
{
  /**
   * Base class for binary expression operators.
   */
  public class BinaryExpression extends Expression
  {
    /** Code indicating the operation perfomed by this instance. */
    protected var _op:int;
    /** The left-hand-side sub-expression. */
    protected var _left:Expression;
    /** The right-hand-side sub-expression. */
    protected var _right:Expression;

    /** Code indicating the operation performed by this instance. */
    public function get operator():int
    {
      return _op;
    }

    public function set operator(op:int):void
    {
      _op = op;
    }
    /** String representation of the operation performed by this
     *  instance. */
    public function get operatorString():String
    {
      return null;
    }

    /** The left-hand-side sub-expression. */
    public function get left():Expression
    {
      return _left;
    }

    public function set left(l:*):void
    {
      _left = Expression.expr(l);
    }

    /** The right-hand-side sub-expression. */
    public function get right():Expression
    {
      return _right;
    }

    public function set right(r:*):void
    {
      _right = Expression.expr(r);
    }

    /**
     * @inheritDoc
     */
    public override function get numChildren():int
    {
      return 2;
    }

    // --------------------------------------------------------------------

    /**
     * Creates a new BinaryExpression.
     * @param op the operation code
     * @param minOp the minimum legal operation code
     * @param maxOp the maximum legal operation code
     * @param left the left-hand-side sub-expression
     * @param right the right-hand-side sub-expression
     */
    public function BinaryExpression(op:int, minOp:int, maxOp:int, left:*, right:*)
    {
      // operation check
      if(op < minOp || op > maxOp)
      {
        throw new ArgumentError("Unknown operation type: " + op);
      }

      // null check
      if(left == null || right == null)
      {
        throw new ArgumentError("Expressions must be non-null.");
      }
      _op = op;
      this.left = left;
      this.right = right;
    }

    /**
   * @inheritDoc
   */
    public override function getChildAt(idx:int):Expression
    {
      switch (idx)
      {
        case 0: return _left;

        case 1: return _right;
        default: return null;
      }
    }

    /**
   * @inheritDoc
   */
    public override function setChildAt(idx:int, expr:Expression):Boolean
    {
      switch (idx)
      {
        case 0:
          _left = expr;
        return true;

        case 1: _right = expr;
        return true;
        default: return false;
      }
    }

    /**
   * @inheritDoc
   */
    public override function toString():String
    {
      return '(' + _left.toString() + ' '
        + operatorString + ' '
        + _right.toString() + ')';
    }
  } // end of class BinaryExpression
}